package com.ty.superapi.filter;

import com.ty.superapi.util.Result;
import com.ty.superapi.util.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * controller异常统一处理
 *
 * @author tianyu
 * @since 2017/11/15
 */
@ControllerAdvice
@ResponseBody
public class WebExceptionHandler {

    private static Logger log = LoggerFactory.getLogger(WebExceptionHandler.class);

    //运行时异常
    @ExceptionHandler(RuntimeException.class)
    public String runtimeExceptionHandler(RuntimeException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._1000);
    }

    //空指针异常
    @ExceptionHandler(NullPointerException.class)
    public String nullPointerExceptionHandler(NullPointerException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._1001);
    }

    //类型转换异常
    @ExceptionHandler(ClassCastException.class)
    public String classCastExceptionHandler(ClassCastException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._1002);
    }

    //IO异常
    @ExceptionHandler(IOException.class)
    public String iOExceptionHandler(IOException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._1003);
    }

    //未知方法异常
    @ExceptionHandler(NoSuchMethodException.class)
    public String noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._1004);
    }

    //数组越界异常
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._1005);
    }

    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public String requestNotReadable(HttpMessageNotReadableException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._406);
    }

    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    public String requestTypeMismatch(TypeMismatchException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._400);
    }

    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public String requestMissingServletRequest(MissingServletRequestParameterException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._406);
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public String request405(HttpRequestMethodNotSupportedException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._406);
    }

    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    public String request406(HttpMediaTypeNotAcceptableException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._406);
    }

    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public String server500(RuntimeException ex) {
        log.error("异常:" + ex.getMessage(), ex);
        return Result.error(StatusCode._406);
    }
    // 参数绑定异常
    @ExceptionHandler(BindException.class)
    public String validExceptionHandler(BindException ex) {
        log.error("异常:" + ex.getMessage());
        List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();
        Map<String, String> map = new HashMap<String, String>();
        for (FieldError error : fieldErrors) {
            map.put(error.getField(), error.getDefaultMessage());
        }
        return Result.error(StatusCode._2013, map);
    }
}
